package cn.yunyichina.provider.hymed.service.impl;

import cn.yunyichina.provider.hymed.constant.NeusoftFunctionId;
import cn.yunyichina.provider.hymed.constant.ResponseEnum;
import cn.yunyichina.provider.hymed.model.bo.*;
import cn.yunyichina.provider.hymed.model.domain.HymedPaymentSettingDO;
import cn.yunyichina.provider.hymed.model.vo.BaseRequestVO;
import cn.yunyichina.provider.hymed.service.PaymentService;
import cn.yunyichina.provider.hymed.service.neusoft.NeusoftBaseService;
import cn.yunyichina.provider.hymed.service.neusoft.NeusoftService;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.dto.hymed.*;
import cn.yunyichina.utils.dozer.Dozer;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * Created by Lullaby on 2017/10/25
 */
@Service
public class PaymentServiceImpl extends NeusoftBaseService implements PaymentService {

    private static final Logger logger = LoggerFactory.getLogger(PaymentServiceImpl.class);

    private final NeusoftService neusoftService;

    @Autowired
    public PaymentServiceImpl(NeusoftService neusoftService) {
        this.neusoftService = neusoftService;
    }

    /**
     * 社保卡消费
     *
     * @param payRequestDTO
     * @return
     */
    @Override
    public ResCommon<PaymentConsumeResponseDTO> consumePayment(PaymentConsumeRequestDTO payRequestDTO) {
        logger.info("PaymentServiceImpl.consumePayment.payRequestDTO -> {}", JSON.toJSONString(payRequestDTO));

        try {
            PaymentConsumeRequestBO payRequestBO = Dozer.convert(payRequestDTO, PaymentConsumeRequestBO.class);
            BaseRequestVO baseRequestVO = new BaseRequestVO();
            baseRequestVO.setAppCode(payRequestDTO.getAppCode());
            baseRequestVO.setOrgCode(payRequestDTO.getOrgCode());
            baseRequestVO.setPayCode(payRequestDTO.getPayCode());
            HymedPaymentSettingDO hymedPaymentSettingDO=getNeusoftSessionId(baseRequestVO);
            payRequestBO.setSession_id(hymedPaymentSettingDO.getSessionId());
            payRequestBO.setPrivateKey(hymedPaymentSettingDO.getPrivateKey());
            payRequestBO.setPublicKey(hymedPaymentSettingDO.getPublicKey());
            payRequestBO.setFunction_id(NeusoftFunctionId.ORDER_PAY);
            logger.info("PaymentServiceImpl.consumePayment.payRequestBO -> {}", JSON.toJSONString(payRequestBO));

            PaymentConsumeResponseBO payResponseBO = neusoftService.doExecute(payRequestBO, PaymentConsumeResponseBO.class);
            logger.info("PaymentServiceImpl.consumePayment.payResponseBO -> {}", JSON.toJSONString(payResponseBO));

            if (payResponseBO == null || !payResponseBO.getBizSuccess()) {
                return new ResCommon<PaymentConsumeResponseDTO>().buildResultCodeAndMessageAndResult(
                        ResponseEnum.MEDICAL_CARD_PAY_FAIL.getCode(),
                        ResponseEnum.MEDICAL_CARD_PAY_FAIL.getMessage(),
                        Dozer.convert(payResponseBO, PaymentConsumeResponseDTO.class)
                );
            }

            return new ResCommon<PaymentConsumeResponseDTO>().buildResult(Dozer.convert(payResponseBO, PaymentConsumeResponseDTO.class));
        } catch (Exception e) {
            logger.info("PaymentServiceImpl.consumePayment.Exception -> {}", e);
            return new ResCommon<PaymentConsumeResponseDTO>().buildResultCodeAndMessage(
                    ResponseEnum.MEDICAL_CARD_PAY_EXCEPTION.getCode(),
                    ResponseEnum.MEDICAL_CARD_PAY_EXCEPTION.getMessage()
            );
        }
    }

    /**
     * 余额查询
     *
     * @param balanceRequestDTO
     * @return
     */
    @Override
    public ResCommon<PaymentBalanceResponseDTO> balancePayment(PaymentBalanceRequestDTO balanceRequestDTO) {
        logger.info("PaymentServiceImpl.balancePayment.balanceRequestDTO -> {}", JSON.toJSONString(balanceRequestDTO));

        try {
            PaymentBalanceRequestBO balanceRequestBO = Dozer.convert(balanceRequestDTO, PaymentBalanceRequestBO.class);
            BaseRequestVO baseRequestVO = new BaseRequestVO();
            baseRequestVO.setAppCode(balanceRequestDTO.getAppCode());
            baseRequestVO.setOrgCode(balanceRequestDTO.getOrgCode());
            baseRequestVO.setPayCode(balanceRequestDTO.getPayCode());
            HymedPaymentSettingDO hymedPaymentSettingDO=getNeusoftSessionId(baseRequestVO);
            balanceRequestBO.setSession_id(hymedPaymentSettingDO.getSessionId());
            balanceRequestBO.setPrivateKey(hymedPaymentSettingDO.getPrivateKey());
            balanceRequestBO.setPublicKey(hymedPaymentSettingDO.getPublicKey());
            balanceRequestBO.setFunction_id(NeusoftFunctionId.QUERY_MEDICAL_CARD_BALANCE);
            logger.info("PaymentServiceImpl.balancePayment.balanceRequestBO -> {}", JSON.toJSONString(balanceRequestBO));

            PaymentBalanceResponseBO balanceResponseBO = neusoftService.doExecute(balanceRequestBO, PaymentBalanceResponseBO.class);
            logger.info("PaymentServiceImpl.balancePayment.balanceResponseBO -> {}", JSON.toJSONString(balanceResponseBO));

            if (balanceResponseBO == null || !balanceResponseBO.getBizSuccess()) {
                return new ResCommon<PaymentBalanceResponseDTO>().buildResultCodeAndMessageAndResult(
                        ResponseEnum.BALANCE_QUERY_FAIL.getCode(),
                        ResponseEnum.BALANCE_QUERY_FAIL.getMessage(),
                        Dozer.convert(balanceResponseBO, PaymentBalanceResponseDTO.class)
                );
            }

            return new ResCommon<PaymentBalanceResponseDTO>().buildResult(Dozer.convert(balanceResponseBO, PaymentBalanceResponseDTO.class));
        } catch (Exception e) {
            logger.info("PaymentServiceImpl.balancePayment.Exception -> {}", e);
            return new ResCommon<PaymentBalanceResponseDTO>().buildResultCodeAndMessage(
                    ResponseEnum.BALANCE_QUERY_EXCEPTION.getCode(),
                    ResponseEnum.BALANCE_QUERY_EXCEPTION.getMessage()
            );
        }
    }

    /**
     * 消费撤销
     *
     * @param revokeRequestDTO
     * @return
     */
    @Override
    public ResCommon<PaymentRevokeResponseDTO> revokePayment(PaymentRevokeRequestDTO revokeRequestDTO) {
        logger.info("PaymentServiceImpl.revokePayment.revokeRequestDTO -> {}", JSON.toJSONString(revokeRequestDTO));

        try {
            PaymentRevokeRequestBO revokeRequestBO = Dozer.convert(revokeRequestDTO, PaymentRevokeRequestBO.class);
            BaseRequestVO baseRequestVO = new BaseRequestVO();
            baseRequestVO.setAppCode(revokeRequestDTO.getAppCode());
            baseRequestVO.setOrgCode(revokeRequestDTO.getOrgCode());
            baseRequestVO.setPayCode(revokeRequestDTO.getPayCode());
            HymedPaymentSettingDO hymedPaymentSettingDO=getNeusoftSessionId(baseRequestVO);
            revokeRequestBO.setSession_id(hymedPaymentSettingDO.getSessionId());
            revokeRequestBO.setPrivateKey(hymedPaymentSettingDO.getPrivateKey());
            revokeRequestBO.setPublicKey(hymedPaymentSettingDO.getPublicKey());
            revokeRequestBO.setFunction_id(NeusoftFunctionId.ORDER_CANCEL);
            logger.info("PaymentServiceImpl.revokePayment.revokeRequestBO -> {}", JSON.toJSONString(revokeRequestBO));

            PaymentRevokeResponseBO revokeResponseBO = neusoftService.doExecute(revokeRequestBO, PaymentRevokeResponseBO.class);
            logger.info("PaymentServiceImpl.revokePayment.revokeResponseBO -> {}", JSON.toJSONString(revokeResponseBO));

            if (revokeResponseBO == null || !revokeResponseBO.getBizSuccess()) {
                return new ResCommon<PaymentRevokeResponseDTO>().buildResultCodeAndMessageAndResult(
                        ResponseEnum.CONSUME_REVOKE_FAIL.getCode(),
                        ResponseEnum.CONSUME_REVOKE_FAIL.getMessage(),
                        Dozer.convert(revokeResponseBO, PaymentRevokeResponseDTO.class)
                );
            }

            return new ResCommon<PaymentRevokeResponseDTO>().buildResult(Dozer.convert(revokeResponseBO, PaymentRevokeResponseDTO.class));
        } catch (Exception e) {
            logger.info("PaymentServiceImpl.revokePayment.Exception -> {}", e);
            return new ResCommon<PaymentRevokeResponseDTO>().buildResultCodeAndMessage(
                    ResponseEnum.CONSUME_REVOKE_EXCEPTION.getCode(),
                    ResponseEnum.CONSUME_REVOKE_EXCEPTION.getMessage()
            );
        }
    }

    /**
     * 消费查询
     *
     * @param queryRequestDTO
     * @return
     */
    @Override
    public ResCommon<PaymentQueryResponseDTO> queryPayment(PaymentQueryRequestDTO queryRequestDTO) {
        logger.info("PaymentServiceImpl.queryPayment.queryRequestDTO -> {}", JSON.toJSONString(queryRequestDTO));

        try {
            PaymentQueryRequestBO queryRequestBO = Dozer.convert(queryRequestDTO, PaymentQueryRequestBO.class);
            BaseRequestVO baseRequestVO = new BaseRequestVO();
            baseRequestVO.setAppCode(queryRequestDTO.getAppCode());
            baseRequestVO.setOrgCode(queryRequestDTO.getOrgCode());
            baseRequestVO.setPayCode(queryRequestDTO.getPayCode());
            HymedPaymentSettingDO hymedPaymentSettingDO=getNeusoftSessionId(baseRequestVO);
            queryRequestBO.setSession_id(hymedPaymentSettingDO.getSessionId());
            queryRequestBO.setPrivateKey(hymedPaymentSettingDO.getPrivateKey());
            queryRequestBO.setPublicKey(hymedPaymentSettingDO.getPublicKey());
            queryRequestBO.setFunction_id(NeusoftFunctionId.ORDER_QUERY);
            logger.info("PaymentServiceImpl.queryPayment.queryRequestBO -> {}", JSON.toJSONString(queryRequestBO));

            PaymentQueryResponseBO queryResponseBO = neusoftService.doExecute(queryRequestBO, PaymentQueryResponseBO.class);
            logger.info("PaymentServiceImpl.queryPayment.queryResponseBO -> {}", JSON.toJSONString(queryResponseBO));

            if (queryResponseBO == null || !queryResponseBO.getBizSuccess()) {
                return new ResCommon<PaymentQueryResponseDTO>().buildResultCodeAndMessageAndResult(
                        ResponseEnum.CONSUME_QUERY_FAIL.getCode(),
                        ResponseEnum.CONSUME_QUERY_FAIL.getMessage(),
                        Dozer.convert(queryResponseBO, PaymentQueryResponseDTO.class)
                );
            }

            return new ResCommon<PaymentQueryResponseDTO>().buildResult(Dozer.convert(queryResponseBO, PaymentQueryResponseDTO.class));
        } catch (Exception e) {
            logger.info("PaymentServiceImpl.queryPayment.Exception -> {}", e);
            return new ResCommon<PaymentQueryResponseDTO>().buildResultCodeAndMessage(
                    ResponseEnum.CONSUME_QUERY_EXCEPTION.getCode(),
                    ResponseEnum.CONSUME_QUERY_EXCEPTION.getMessage()
            );
        }
    }

}
